package com.ideaaedi.commonspring.spi;

import com.ideaaedi.commonspring.aop.AntiDuplicationAdvice;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

/**
 * 防重执行器
 *
 * @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img
 * src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
 * @since 2100.7.3
 */
public interface AntiDuplicateExecutor<R> {
    
    /**
     * 设置{@link AntiDuplicationAdvice}的aop优先级
     */
    int adviceOrder();
    
    /**
     * 防重执行逻辑
     *
     * @param invocation 方法调用对象
     * @return 返回结果
     */
    R exec(@NonNull MethodInvocation invocation);
    
    /**
     * 依次执行完{@link AntiDuplicateExecutor#exec(MethodInvocation)}、{@link MethodInvocation#proceed()}方法后，会执行此方法
     * <br />
     * 注：无论{@link AntiDuplicateExecutor#exec(MethodInvocation)}是否发生异常、无论切面目标方法{@link MethodInvocation#proceed()}是否发生异常，都会执行此方法
     *
     * @param throwable 异常  <br />{@link AntiDuplicateExecutor#exec(MethodInvocation)}或{@link MethodInvocation#proceed()}所发生的异常
     * @param execResult 方法调用对象 <br />{@link AntiDuplicateExecutor#exec(MethodInvocation)}的返回结果
     * @param targetPointResult 方法调用对象<br />{@link MethodInvocation#proceed()}的返回结果
     */
    default void doFinally(@Nullable Throwable throwable, @Nullable R execResult, @Nullable Object targetPointResult) {
    }
}
